/**
 * 导入绘制上下文类型
 */
import { RequestLayoutState as PaintRequestLayoutState, PrepaintState as PaintPrepaintState, PaintContext as PaintPaintContext } from './paint_context';

/**
 * 重新导出类型，保持兼容性
 */
export type RequestLayoutState = PaintRequestLayoutState;
export type PrepaintState = PaintPrepaintState;
export type PaintContext = PaintPaintContext;

/**
 * 全局元素ID
 */
export class GlobalElementId {
  private static nextId = 1
  private id: number

  constructor() {
    this.id = GlobalElementId.nextId++
  }

  toString(): string {
    return `element-${this.id}`
  }
}

/**
 * 元素接口，所有UI元素都必须实现此接口
 */
export interface Element {
  // 关联类型
  RequestLayoutState: RequestLayoutState
  PrepaintState: PrepaintState

  // 核心方法
  id(): GlobalElementId
  sourceLocation(): string | null
  requestLayout(state: RequestLayoutState): void
  prepaint(state: PrepaintState): void
  paint(context: PaintContext): HTMLElement
  intoAny(): AnyElement

  // 可选的DOM相关方法
  render?(): HTMLElement
}

/**
 * 可转换为元素的接口
 */
export interface IntoElement<T extends Element> {
  intoElement(): T
}

/**
 * 渲染器接口
 */
export interface Render {
  render(): Element
}

/**
 * 一次性渲染器接口
 */
export interface RenderOnce {
  render(): Element
}

/**
 * 父元素接口
 */
export interface ParentElement<T extends Element> extends Element {
  addChild(child: T): void
  removeChild(child: T): void
  children(): ReadonlyArray<T>
}

/**
 * 可绘制接口
 */
export interface Drawable {
  requestLayout(): void
  prepaint(state: PrepaintState): void
  paint(context: PaintContext): HTMLElement
}

/**
 * 元素绘制阶段
 */
export enum ElementDrawPhase {
  RequestLayout,
  Layout,
  Prepaint,
  Paint
}

/**
 * 任意元素接口
 */
export interface AnyElement extends Element {
  asElement(): Element
}

/**
 * 基础元素实现
 */
export abstract class BaseElement implements Element {
  private elementId: GlobalElementId
  
  constructor() {
    this.elementId = new GlobalElementId()
  }

  id(): GlobalElementId {
    return this.elementId
  }

  sourceLocation(): string | null {
    return null
  }

  abstract requestLayout(state: RequestLayoutState): void
  abstract prepaint(state: PrepaintState): void
  abstract paint(context: PaintContext): HTMLElement
  
  intoAny(): AnyElement {
    const anyElement: any = {
      id: this.id.bind(this),
      sourceLocation: this.sourceLocation.bind(this),
      requestLayout: this.requestLayout.bind(this),
      prepaint: this.prepaint.bind(this),
      paint: this.paint.bind(this),
      intoAny: this.intoAny.bind(this),
      asElement: (): Element => this
    }
    
    // 添加关联类型
    anyElement.RequestLayoutState = this.RequestLayoutState
    anyElement.PrepaintState = this.PrepaintState
    
    return anyElement
  }

  render(): HTMLElement {
    // 在没有scene的情况下，创建一个最小的上下文
    const minimalContext = { document, scene: null } as any;
    return this.paint(minimalContext)
  }

  // 关联类型
  RequestLayoutState!: RequestLayoutState
  PrepaintState!: PrepaintState
}